<?php

namespace App\Services;

use App\Http\Resources\TermResource;
use Illuminate\Http\Request;

/**
 * 分类层级关系服务类
 * 优化嵌套查询，避免N+1查询问题
 */
class TermHierarchyService
{
    /**
     * 构建分类层级关系
     *
     * @param array $terms 分类数组
     * @param Request $request 请求对象
     * @param string $taxonomy 分类法类型
     * @return array
     */
    public static function buildHierarchy(array $terms, Request $request, string $taxonomy = 'category'): array
    {
        if (empty($terms)) {
            return [];
        }

        // 如果不需要包含子分类，直接返回
        if (!$request->boolean('include_children', false)) {
            return self::formatTermsWithoutChildren($terms, $request);
        }

        // 获取所有分类的ID
        $termIds = array_map(function ($term) {
            return is_object($term) ? $term->term_id : $term['term_id'];
        }, $terms);

        // 批量查询所有子分类（包括子分类的子分类）
        $allChildren = self::getAllChildren($termIds, $taxonomy);

        // 构建父子关系映射
        $childrenMap = self::buildChildrenMap($allChildren);

        // 构建层级结构
        return self::buildNestedStructure($terms, $childrenMap, $request);
    }

    /**
     * 格式化不包含子分类的分类数据
     *
     * @param array $terms
     * @param Request $request
     * @return array
     */
    private static function formatTermsWithoutChildren(array $terms, Request $request): array
    {
        return array_map(function ($term) use ($request) {
            $resource = new TermResource($term);
            return $resource->toArray($request);
        }, $terms);
    }

    /**
     * 递归获取所有子分类
     *
     * @param array $parentIds 父级ID数组
     * @param string $taxonomy 分类法类型
     * @return array
     */
    private static function getAllChildren(array $parentIds, string $taxonomy): array
    {
        if (empty($parentIds)) {
            return [];
        }

        $allChildren = [];
        $currentLevel = $parentIds;

        // 递归查询所有层级的子分类
        while (!empty($currentLevel)) {
            $children = get_terms([
                'taxonomy' => $taxonomy,
                'parent__in' => $currentLevel,
                'hide_empty' => false,
            ]);

            if (is_wp_error($children) || empty($children)) {
                break;
            }

            $allChildren = array_merge($allChildren, $children);
            $currentLevel = array_map(function ($child) {
                return is_object($child) ? $child->term_id : $child['term_id'];
            }, $children);
        }

        return $allChildren;
    }

    /**
     * 构建父子关系映射表
     *
     * @param array $children 所有子分类
     * @return array
     */
    private static function buildChildrenMap(array $children): array
    {
        $childrenMap = [];

        foreach ($children as $child) {
            $parentId = is_object($child) ? $child->parent : $child['parent'];
            $childId = is_object($child) ? $child->term_id : $child['term_id'];

            if (!isset($childrenMap[$parentId])) {
                $childrenMap[$parentId] = [];
            }

            $childrenMap[$parentId][] = $child;
        }

        return $childrenMap;
    }

    /**
     * 构建嵌套结构
     *
     * @param array $terms 顶级分类
     * @param array $childrenMap 子分类映射
     * @param Request $request 请求对象
     * @return array
     */
    private static function buildNestedStructure(array $terms, array $childrenMap, Request $request): array
    {
        $result = [];

        foreach ($terms as $term) {
            $termId = is_object($term) ? $term->term_id : $term['term_id'];

            // 创建分类资源
            $resource = new TermResource($term);
            $termData = $resource->toArray($request);

            // 添加子分类
            if (isset($childrenMap[$termId])) {
                $termData['children'] = self::buildNestedStructure(
                    $childrenMap[$termId],
                    $childrenMap,
                    $request
                );
            } else {
                $termData['children'] = [];
            }

            $result[] = $termData;
        }

        return $result;
    }

    /**
     * 获取单个分类的完整层级结构
     *
     * @param object $term 分类对象
     * @param Request $request 请求对象
     * @return array
     */
    public static function buildSingleTermHierarchy($term, Request $request): array
    {
        if (!$request->boolean('include_children', false)) {
            $resource = new TermResource($term);
            return $resource->toArray($request);
        }

        $termId = is_object($term) ? $term->term_id : $term['term_id'];
        $taxonomy = is_object($term) ? $term->taxonomy : $term['taxonomy'];

        // 获取所有子分类
        $allChildren = self::getAllChildren([$termId], $taxonomy);
        $childrenMap = self::buildChildrenMap($allChildren);

        // 构建嵌套结构
        $resource = new TermResource($term);
        $termData = $resource->toArray($request);
        $termData['children'] = self::buildNestedStructure(
            $childrenMap[$termId] ?? [],
            $childrenMap,
            $request
        );

        return $termData;
    }
}
